import numpy as np
from scipy.io import wavfile
import os

def generate_piano_note(freq, duration=1.0, sample_rate=44100, amplitude=0.5):
    # 生成时间序列
    t = np.linspace(0, duration, int(sample_rate * duration))
    
    # 基础频率的正弦波
    fundamental = np.sin(2 * np.pi * freq * t)
    
    # 添加泛音以模拟钢琴音色
    harmonics = [
        0.5 * np.sin(2 * np.pi * (2 * freq) * t),  # 第一泛音
        0.3 * np.sin(2 * np.pi * (3 * freq) * t),  # 第二泛音
        0.2 * np.sin(2 * np.pi * (4 * freq) * t),  # 第三泛音
    ]
    
    # 合并基频和泛音
    note = fundamental + sum(harmonics)
    
    # 应用包络（ADSR）
    envelope = np.ones_like(t)
    attack_time = 0.05
    decay_time = 0.1
    sustain_level = 0.7
    release_time = 0.3
    
    attack_samples = int(attack_time * sample_rate)
    decay_samples = int(decay_time * sample_rate)
    release_samples = int(release_time * sample_rate)
    
    # Attack
    envelope[:attack_samples] = np.linspace(0, 1, attack_samples)
    # Decay
    envelope[attack_samples:attack_samples+decay_samples] = np.linspace(1, sustain_level, decay_samples)
    # Release
    release_start = len(envelope) - release_samples
    envelope[release_start:] = np.linspace(sustain_level, 0, release_samples)
    
    # 应用包络
    note = note * envelope
    
    # 归一化
    note = note / np.max(np.abs(note))
    
    # 调整音量
    note = note * amplitude
    
    # 创建立体声
    stereo_note = np.vstack((note, note)).T
    
    # 转换为16位整数
    return (stereo_note * 32767).astype(np.int16)

def main():
    # 确保sounds目录存在
    if not os.path.exists('sounds'):
        os.makedirs('sounds')
    
    # A0的频率是27.5Hz
    base_freq = 27.5
    
    # 生成52个音符（从A0到C8）
    for i in range(52):
        # 计算频率（每个半音的频率是前一个音符的频率乘以2的1/12次方）
        freq = base_freq * (2 ** (i / 12))
        
        # 生成音符
        note = generate_piano_note(freq)
        
        # 保存为WAV文件
        filename = f'sounds/piano_{i}.wav'
        wavfile.write(filename, 44100, note)
        print(f'Generated {filename}')

if __name__ == '__main__':
    main()